interface LSOptions {
  namespace?: string
}

export const ls = {
  getNamespace(name: string): string {
    return `${this.options.namespace || ''}${name}`;
  },

  set(name: string, value: any, expire: number | null = null): void {
    const stringifyValue = JSON.stringify({
      value,
      expire: expire !== null ? new Date().getTime() + expire : null
    });
    uni.setStorageSync(this.getNamespace(name), stringifyValue);
  },

  get<T>(name: string, def: T | null = null): T | null {
    const item = uni.getStorageSync(this.getNamespace(name));
    if (item !== null && item !== '') {
      try {
        const data = JSON.parse(item) as { value: T, expire: number | null };
        if (data.expire === null) {
          return data.value;
        }
        if (data.expire >= new Date().getTime()) {
          return data.value;
        }
        ls.remove(name);
      }
      catch (err) {
        console.error('>>>>ls.get', name, item, err);
        return def;
      }
    }
    return def;
  },

  remove(name: string): void {
    uni.removeStorageSync(this.getNamespace(name));
  },

  clear(): void {
    const keys: string[] = uni.getStorageInfoSync().keys;
    const removedKeys: string[] = [];

    for (const key of keys) {
      if (key.startsWith(this.getNamespace(''))) {
        removedKeys.push(key);
      }
    }

    for (const key of removedKeys) {
      uni.removeStorageSync(key);
    }
  },

  options: {} as LSOptions,

  setOptions(options: LSOptions): void {
    this.options = options;
  }
};
